// Copyright [2022] <Tianyu Zhu, Shizhen Zhao, Zihang Ren>

#include <iostream>
#include <unordered_set>
#include "graph.h"
#include "pulse.h"
#include "pulse_plus.h"
#include "double_pulse.h"
// #include "stack_pulse.h"
#include "srlg_pulse.h"

void test(std::string file_path)
{
    Graph graph(file_path);
    std::cout << "\n--------------------------\n";
    std::cout << file_path << std::endl;
    std::cout << "Number of Nodes: " << graph.NodeSize()
              << "\nNumber of links: " << graph.LinkSize() << std::endl;
    Demand demand(file_path);
    std::cout << "Number of Flows: " << demand.NumFlows() << "\n";
    SrlgPulse pulse;
    pulse.SetupTopology(&graph);
    for (int i = 0; i < demand.NumFlows(); ++i)
    {
        demand.GetFlow(i).Print();
        if (demand.GetFlow(i).is_diff)
        {
            if (demand.GetFlow(i).type == 0)
                std::cout << "**Link Separate**\n";
            if (demand.GetFlow(i).type == 1)
                std::cout << "**Node Separate**\n";
            if (demand.GetFlow(i).type == 2)
                std::cout << "**Srlg Separate**\n";
            PathPair path =  pulse.FindPathPair(demand.GetFlow(i));
            path.Print();
        }
        else
        {
            std::cout << "**Delay Range**\n";
            Path path = pulse.FindPath(demand.GetFlow(i));
            path.Print();
        }

        pulse.print();
    }
}

void delay_range_test()
{
    std::vector<std::string> directories = {
        "case_10", "case_13", "case_16", "case_18", "case_20",
        "case_24", "case_26", "case_28", "case_30", "case_11",
        "case_15", "case_17", "case_19", "case_21", "case_25",
        "case_27", "case_29"};
    for (std::string dir : directories)
    {
        std::string file_path = "data/DelayRange/large/" + dir + "/";
        test(file_path);
    }
    directories = {
        "case_0", "case_4", "case_5", "case_7", "case_8",
        "case_9", "case_10", "case_11", "case_12", "case_13",
        "case_15", "case_16", "case_17", "case_18", "case_20"};
    for (std::string dir : directories)
    {
        std::string file_path = "data/DelayRange/middle/" + dir + "/";
        test(file_path);
    }
    test("data/DelayRange/dc2/");
    test("data/DelayRange/dc5/");
}

void delay_diff_test()
{   
    test("data/DelayDiff/dc2/");
    test("data/DelayDiff/dc5/");
    
    // test("data/DelayDiff/case2/");
    test("data/DelayDiff/case3/");
    // test("data/DelayDiff/case7/");
    std::vector<std::string> directories = {
        "case_31", "case_32", "case_33", "case_34", "case_35",
        "case_36", "case_37", "case_38", "case_39", "case_40",
        "case_41", "case_42", "case_43", "case_44", "case_45",
        "case_46", "case_47", "case_48", "case_49"};
    for (std::string dir : directories)
    {
        std::string file_path = "data/DelayDiff/large/" + dir + "/";
        test(file_path);
    }
    directories = {
        "case_0", "case_2", "case_4", "case_5", "case_6",
        "case_7", "case_8", "case_9", "case_10", "case_11",
        "case_12", "case_13", "case_15", "case_17",
        "case_18", "case_19", "case_20"};
    for (std::string dir : directories)
    {
        std::string file_path = "data/DelayDiff/middle/" + dir + "/";
        test(file_path);
    }
}   
    
int main()
{   
    // delay_range_test();
    delay_diff_test();
    test("data/functioncase/");
    // test("data/DelayDiff/case7/");
    return 0;
}   
